// <copyright file="AccountService.cs" company="Clever Software">
// Copyright (c) 2013, 2014 All Right Reserved, http://www.cleversoftware.by
//
// This source is subject to the Microsoft Permissive License.
// Please see the License.txt file for more information.
// All other rights reserved.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// </copyright>
// <author>Clever Software</author>
// <email>info@cleversoftware.by</email>
// <date>2014-02-04</date> 
// <summary>CleverCMS source code</summary>

namespace CleverCMS.Cms.Services
{
    using System.Linq;
    using System.Collections.Generic;
   
    using CleverCMS.Cms.Data.Entities;
    using CleverCMS.Cms.Data;
    using CleverCMS.Core.Infrastructure;

    public class AccountService
    {
        private readonly ICmsGenericRepository<UserProfile>    m_userRepo;
        private readonly ICmsGenericRepository<Role>           m_rolesRepo;
        private readonly AppCache                              m_appCache;   

        public AccountService(ICmsGenericRepository<UserProfile>   userRepo, 
                              ICmsGenericRepository<Role>          rolesRepo)
        {
            this.m_userRepo = userRepo;
            this.m_rolesRepo = rolesRepo;
            this.m_appCache = new AppCache();
        }

        #region Users
        /// <summary>
        /// Return all users
        /// </summary>
        /// <returns></returns>
        public IQueryable<UserProfile> LoadAllUsers()
        {
            return m_userRepo.LoadAll();
        }
        /// <summary>
        /// Return all users for paged list
        /// </summary>
        /// <param name="start"></param>
        /// <param name="size"></param>
        /// <param name="sortOrder"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public IQueryable<UserProfile> LoadAllUsers(int start, int size, string sortOrder, out int count)
        {
            var users = m_userRepo.LoadAll(orderBy: q => q.OrderByDescending(d => d.CreatedAt))
                                  .Skip(start)
                                  .Take(size);

            count = m_userRepo.Count();

            return users;
        }
        /// <summary>
        /// Return user by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public UserProfile LoadUser(int id)
        {
            return m_userRepo.Load(id);
        }
        /// <summary>
        /// Updates user
        /// </summary>
        /// <param name="user"></param>
        public void UpdateUser(UserProfile user)
        {
            m_userRepo.Save(user, user.Id == 0);
            m_appCache.Remove("Users");
        }
        /// <summary>
        /// Return user entity by login
        /// </summary>
        /// <param name="userLogin"></param>
        /// <returns></returns>
        public UserProfile FindUser(string userLogin)
        {
            return m_userRepo.LoadAll(filter: x => x.Login == userLogin)
                             .SingleOrDefault();
        }
        /// <summary>
        /// Deletes user by userid
        /// </summary>
        /// <param name="userId"></param>
        public void DeleteUser(int userId)
        {
            m_userRepo.Delete(userId);
            m_appCache.Remove("Users");
        }

        #endregion

        #region Roles
        /// <summary>
        /// Load all roles
        /// </summary>
        /// <returns></returns>
        public IEnumerable<Role> LoadAllRoles()
        {
            return m_rolesRepo.LoadAll();
        }
        /// <summary>
        /// Load all roles for paged list
        /// </summary>
        /// <param name="start"></param>
        /// <param name="size"></param>
        /// <param name="sortOrder"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        public IQueryable<Role> LoadAllRoles(int start, int size, string sortOrder, out int count)
        {
            var users = m_rolesRepo.LoadAll(orderBy: q => q.OrderByDescending(d => d.RoleName))
                                   .Skip(start)
                                   .Take(size);

            count = m_rolesRepo.Count();

            return users;
        }
        /// <summary>
        /// Return role by id
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public Role LoadRole(int id)
        {
            return m_rolesRepo.Load(id);
        }
        /// <summary>
        /// Update role
        /// </summary>
        /// <param name="role"></param>
        public void UpdateRole(Role role)
        {
            m_rolesRepo.Save(role, role.RoleId == 0);
            m_appCache.Remove("Roles");
        }
        /// <summary>
        /// Delete role
        /// </summary>
        /// <param name="roleId"></param>
        public void DeleteRole(int roleId)
        {
            m_rolesRepo.Delete(roleId);
            m_appCache.Remove("Roles");
        }
        /// <summary>
        /// Get Role by name
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public Role GetRoleByName(string name)
        {
            return LoadAllRoles().FirstOrDefault(x => x.RoleName == name);
        }

        #endregion
    }
}